;V-1 
;Compile with Crownhill Proton+ PIC Basic compiler.                                     
;This progam displays on a (2*16) LC-Display (HD44780 4-line mode) the RC5 code.        
;Sys: the decimal- and the binair- system value                                         
;Com: the decimal- and the binair- command value                                        

;Green LED:  Infrared received.                                                         
;Yellow LED: No RC5/RC6 code or glitch.                                                 
;Red LED:    No RC5/RC6 code or bad receiving.                                          
;Toggle LED: RC5/RC6 toggle value (0 or 1).                                             

;Attention: The TSOP1736 (= 36kHz IR-receiver) must connected via a 470 Ohm resistor to 
;           +5V and over the + and - pin a tantalium C of minimal 0,1uF !               
;           Connection TSOP1736: || |                                                   
;                                -+ s                                                   
;           PIC16F628A:                 +--v--+                                         
;                            LED Green <[     ]> LED Red                                
;                           LED Toggle <[     ]> LED Yellow                             
;             Signal from the TSOP1736 >[     ]                                         
;      Via resistor to +5V ---[33k]--- >[     ]                                         
;                                  GND  [     ]  +5V                                    
;                                       [     ]> DB7 LCD                                
;                                       [     ]> DB6 LCD                                
;                               LCD EN <[     ]> DB5 LCD                                
;                               LCD RS <[     ]> DB4 LCD                                
;                                       +-----+                                         
;Er is ook een Nederlandse versie / There is a Dutch version too                        
;www.picbasic.nl / Frits Kieftenbelt, Raalte, Netherlands (Frizie)                      

DEVICE 16F628A
CONFIG INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, BODEN_OFF, LVP_OFF ;No crystal
;XTAL 4                      ;By use of a crystal use a 4MHz type
ALL_DIGITAL TRUE

;Normal aliases (constants)
SYMBOL Glitch      = 52      ;Max 255: Reduction glitches
SYMBOL LED_Time    = 500     ;mSec: Error LED's burning time
SYMBOL Ok          = 50      ;Max 255: Controltime of the RC5 code is received ok

;Logic aliases (constants)
SYMBOL AAN         = 0       ;Reversed ON
SYMBOL FALSE       = 0
SYMBOL OFF         = 0
SYMBOL ON          = 1
SYMBOL TRUE        = 1
SYMBOL UIT         = 1       ;Reversed OFF

;Port aliases, when changing check TRIS also
SYMBOL LED_Yellow  = PORTA.0 ;Connect LED's in serial with 1k resistor between PORT and GND
SYMBOL LED_Red     = PORTA.1
SYMBOL LED_Green   = PORTA.2
SYMBOL LED_Toggle  = PORTA.3
SYMBOL IR_Receiver = PORTA.4 ;TSOP1736
;        76543210
TRISA = %11110000
TRISB = %11111111
PORTB_PULLUPS ON

;BYTE
DIM Command        AS BYTE   ;RC5/RC6 command byte
DIM CommandOld     AS BYTE
DIM Systeem        AS BYTE   ;RC5/RC6 system byte
DIM SysteemOld     AS BYTE
DIM BD1            AS BYTE   ;Byte Dummy
;BIT
DIM CodeRC5X       AS BIT    ;TRUE when it's RC5X code else...
DIM CodeRC6        AS BIT    ;...TRUE if it's RC6 code (else RC5)
DIM CodeRC6Old     AS BIT    ;By switching between RC6 and RC5/RC5X must the LCD been updated
DIM ToggBit        AS BIT    ;RC5/RC6 toggle bit
DIM Value          AS BIT    ;Argument for subroutine "BitOphalen"
DIM ID1            AS BIT    ;bIt Dummy

CLEAR
DELAYMS 500                  ;LC-Display stabilize

CLS: PRINT   "Decoder  UK V-1" ;Program name and version
PRINT AT 2,1,"www.picbasic.nl"

GOTO Start                   ;Jump over the subroutines


;SUBROUTINES                                                                                                            
BitOphalen:
 BD1 = 0
 Value = IR_Receiver         ;Make value 0 or 1 depending from received IR-code
 WHILE IR_Receiver = Value AND BD1 < Ok;Level must change within time 'Ok'
   INC BD1
 WEND
 IF Ok = BD1 THEN ErrorReceiving ;No level-change whitin the 'Ok' time
 
 IF CodeRC6 = TRUE THEN
   Value = 1 - Value         ;RC6 is inverted to RC5/RC5X
   DELAYUS 625               ;525 -  725 ;(889us / 2 = 444) + half from this time to come in the middle of the next bit; 444+222 = 666, - a few usec's for the program itself = about 625
 ELSE
   DELAYUS 1100              ;950 - 1600
 ENDIF
RETURN


;MAINPROGRAM                                                                                                            
Start:
 LED_Green  = OFF
 LED_Yellow = OFF
 LED_Red    = OFF

 BD1 = 0
 WHILE IR_Receiver = UIT: WEND ;Wait for IR receive
 WHILE IR_Receiver = AAN AND BD1 < Glitch
   INC BD1
 WEND
 IF BD1 < Glitch THEN ErrorGlitch

 CommandOld = Command        ;Save old values for repair in case of a error
 SysteemOld = Systeem

 LED_Green  = ON             ;Received an IR-signal

 
;Find out which protocol----------------
 BD1 = 0
 Command = 0                 ;Eerst 0 maken omdat RC5/RC5X bits 6 & 7 niet overschrijft, als RC6 deze eerder hoog heeft gemaakt, blijven deze hoog (=fout)
 Systeem = 0                 ;Eerst 0 maken omdat RC5/RC5X bits 5,6,7 niet overschrijft, als RC6 deze eerder hoog heeft gemaakt, blijven deze hoog (=fout)
 WHILE BD1 < 255 AND IR_Receiver = AAN 
   INC BD1
 WEND
 
 CodeRC5X = FALSE
 CodeRC6  = FALSE
 SELECT CASE BD1
   CASE 25 TO 90             ;RC5X
     CodeRC5X  = TRUE
     Command.6 = 1
     DELAYUS 1280            ; 900 - 1700 (RC5X)
   CASE > 90                 ;RC6
     CodeRC6   = TRUE
   CASE ELSE                 ;RC5
     DELAYUS 2180            ;1800 - 2600 (RC5)
 END SELECT
; --------------------------------------

 
 IF CodeRC6 = TRUE THEN
'  WHILE IR_Receiver = UIT :WEND ;00  Cancelled (Used for examining protocol)
'  WHILE IR_Receiver = AAN :WEND ;1   Cancelled (Used for examining protocol)
   WHILE IR_Receiver = UIT :WEND ;00
   WHILE IR_Receiver = AAN :WEND ;1
   WHILE IR_Receiver = UIT :WEND ;0
   WHILE IR_Receiver = AAN :WEND ;1
   WHILE IR_Receiver = UIT :WEND ;0

   DELAYUS 2000              ;Wait till the last '1' from the header comes (1778us), by this it come in the middle of the first toggle bit
 
   LED_Toggle    = IR_Receiver
   ToggBit       = IR_Receiver
   WHILE ToggBit = IR_Receiver :WEND ;Wait till the inverted part from the togglebit comes

   DELAYUS 1100              ;1000 - 1200; By this it comes in the middle of the first system bit
    
   GOSUB BitOphalen
   Systeem.7 = Value

   GOSUB BitOphalen
   Systeem.6 = Value

   GOSUB BitOphalen
   Systeem.5 = Value
 ELSE
   GOSUB BitOphalen
   LED_Toggle = Value
 ENDIF

 GOSUB BitOphalen
 Systeem.4 = Value

 GOSUB BitOphalen
 Systeem.3 = Value

 GOSUB BitOphalen
 Systeem.2 = Value

 GOSUB BitOphalen
 Systeem.1 = Value

 GOSUB BitOphalen
 Systeem.0 = Value
 

 IF CodeRC6 = TRUE THEN      ;RC5/RC5X has no 6th and 7th bits
   GOSUB BitOphalen
   Command.7 = Value

   GOSUB BitOphalen
   Command.6 = Value
 ENDIF

 GOSUB BitOphalen
 Command.5 = Value

 GOSUB BitOphalen
 Command.4 = Value

 GOSUB BitOphalen
 Command.3 = Value

 GOSUB BitOphalen
 Command.2 = Value

 GOSUB BitOphalen
 Command.1 = Value

 GOSUB BitOphalen
 Command.0 = Value


 IF Systeem <> SysteemOld OR Command <> CommandOld OR CodeRC6 <> CodeRC6Old THEN ;Without this line the LCD blinks when receiving IR signal (because of CLS)
   CLS
   IF CodeRC5X = TRUE THEN
     PRINT "RC5X"
   ELSEIF CodeRC6 = TRUE THEN
     PRINT "RC6"
   ELSE
     PRINT "RC5"
   ENDIF
   PRINT   " Protocol"
   DELAYMS 1000              ;Time for indication RC5, RC5X or RC6 protocol
   
   CLS
   PRINT "Sys:",  DEC Systeem
   PRINT AT 1, 9, BIN Systeem
   PRINT AT 2, 1, "Com:", DEC Command
   PRINT AT 2, 9, BIN Command
 ENDIF

;Don't put this line at the beginning near Start, else is would also reset when a glitch is received
 CodeRC6Old = CodeRC6        ;By switching between RC6 and RC5/RC5X must the LCD been updated
GOTO Start


ErrorGlitch:
 LED_Yellow = ON             ;Receive error (No RC5 code or glitch)
 DELAYMS LED_Time
GOTO Start


ErrorReceiving:
 LED_Green = OFF
 LED_Red   = ON              ;No RC5 code or no optimal receiving
 DELAYMS LED_Time
 Command = CommandOld        ;Repair Command and Systeem
 Systeem = SysteemOld
GOTO Start